package cn.ylyhappy.netdemo.config

import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.DeviceUtils
import com.blankj.utilcode.util.EncodeUtils
import com.blankj.utilcode.util.EncryptUtils
import com.blankj.utilcode.util.NetworkUtils
import com.blankj.utilcode.util.SPStaticUtils
import com.google.gson.Gson
import okhttp3.CacheControl
import okhttp3.FormBody
import okhttp3.Interceptor
import okhttp3.Response
import okio.Buffer

class CniaoInterceptor : Interceptor {
    companion object {
        private const val TAG = "CniaoInterceptor"
    }

    private val mGson = Gson()

    override fun intercept(chain: Interceptor.Chain): Response {
        val originRequest = chain.request()
        // 附加的公共headers
        val attachHeaders = mutableListOf(
            "appid" to NET_CONFIG_APPID,
            "platform" to "android",
            "timestamp" to System.currentTimeMillis().toString(),
            "brand" to DeviceUtils.getManufacturer(),
            "model" to DeviceUtils.getModel(),
            "uuid" to DeviceUtils.getUniqueDeviceId(),
            "network" to NetworkUtils.getNetworkType().name,
//            "version" to AppUtils.getAppVersionName()

        )

        val tokenstr = "xxxx"
        val localToken = SPStaticUtils.getString(SP_KEY_USER_TOKEN, tokenstr)
        if (localToken.isNotEmpty()) {
            attachHeaders.add("token" to localToken)
        }
        originRequest.url.queryParameterNames.forEach { key ->
            attachHeaders.add(key to (EncodeUtils.urlEncode(originRequest.url.queryParameter(key) ?: "")))
        }

        val requestBody = originRequest.body
        if (originRequest.method == "POST") {
            if (requestBody is FormBody) {
                for (i in 0 until requestBody.size) {
                    attachHeaders.add(requestBody.name(i) to requestBody.value(i))
                }
            }

            if (requestBody?.contentType()?.type == "application"
                && requestBody.contentType()?.subtype == "json"
            ) {
                kotlin.runCatching {
                    val buffer = Buffer()
                    requestBody.writeTo(buffer)
                    buffer.readByteString().utf8()
                }.onSuccess {
                    val map = mGson.fromJson<Map<String, Any>>(it, Map::class.java)
                    map.forEach { entry ->
                        attachHeaders.add(entry.key to entry.value.toString())
                    }
                }
            }
        }

        val sign = attachHeaders
            .sortedBy { it.first }
            .joinToString ("&") {"${it.first}=${it.second}"}
            .plus("&appkey=$NET_CONFIG_APPID")

        val newBuilder = originRequest.newBuilder()
            .cacheControl(CacheControl.FORCE_NETWORK)
        attachHeaders.forEach { newBuilder.header(it.first, it.second) }
        newBuilder.header("sign", EncryptUtils.encryptMD5ToString(sign))
        if (originRequest.method == "POST" && requestBody != null){
            newBuilder.post(requestBody)
        } else if (originRequest.method == "GET"){
            newBuilder.get()
        }
        return chain.proceed(newBuilder.build())
    }
}